package cn.merge;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import static org.apache.poi.ss.usermodel.CellType.BLANK;
import static org.apache.poi.ss.usermodel.CellType.NUMERIC;
import static org.apache.poi.ss.usermodel.CellType.STRING;

@SuppressWarnings("unused")
@Slf4j
public class POIDataReader {


	/**
	 * 输入流
	 */
	private final InputStream inputStream;

	/**
	 * execl
	 */
	private Workbook workbook;

	/**
	 * sheet对象
	 */
	private Sheet sheet;

	private Row row;

	@SuppressWarnings("unused")
	public POIDataReader(InputStream inputStream) {
		this.inputStream = inputStream;
		this.createWorkbook(inputStream);
	}

	/**
	 * 创建workbook
	 *
	 * @param inputStream input
	 */
	private void createWorkbook(InputStream inputStream) {
		try {
			//创建 excel
			workbook = WorkbookFactory.create(inputStream);
		} catch (Exception e) {
			log.error("Excel文件解析失败!", e);
		}
	}


	/**
	 * 读取Excel表格表头的内容
	 *
	 * @param sheetAt 第几个sheet
	 * @return String 表头内容的数组
	 */
	@SuppressWarnings("unused")
	public String[] readExcelTitle(int sheetAt) {
		String[] title = null;

		if (inputStream != null) {
			try {
				if (null == workbook) {
					workbook = WorkbookFactory.create(inputStream);
				}
				sheet = workbook.getSheetAt(sheetAt);
				row = sheet.getRow(0);
				// 标题总列数
				int colNum = row.getPhysicalNumberOfCells();
				title = new String[colNum];
				for (int i = 0; i < colNum; i++) {
					title[i] = getStringCellValue(row.getCell(i));
				}
			} catch (Exception e) {
				log.error("Excel文件解析失败!", e);
			}
		}

		return title;
	}


	/**
	 * 读取Excel数据内容
	 * (默认第一行数据去除，标题头)
	 *
	 * @return Map 包含单元格数据内容的Map对象
	 */
	public Map<Integer, List<String[]>> readExcelContent() {
		return readExcelContent(1);
	}

	/**
	 * 读取Excel数据内容
	 * (默认第一行数据去除，标题头)
	 *
	 * @return Map 包含单元格数据内容的Map对象
	 */
	public Map<Integer, List<String[]>> readExcelContent(Integer lineNumber) {
		Map<Integer, List<String[]>> content = new HashMap<>(16);
		if (inputStream != null) {
			try {
				int sheetNum = workbook.getNumberOfSheets();
				for (int s = 0; s < sheetNum; s++) {
					List<String[]> sheetContent = new ArrayList<>();
					sheet = workbook.getSheetAt(s);
					// 得到总行数
					int rowNum = sheet.getLastRowNum();
					row = sheet.getRow(0);
					if (row != null) {
						int colNum = row.getPhysicalNumberOfCells();
						// 正文内容应该从第二行开始,第一行为表头的标题
						List<String> values;
						for (int i = lineNumber; i <= rowNum; i++) {
							row = sheet.getRow(i);
							if (row != null) {
								values = new ArrayList<>();
								int j = 0;
								while (j < colNum) {
									values.add(getStringCellValue(row.getCell(j)).trim());
									j++;
								}
								sheetContent.add(values.toArray(new String[0]));

							}
							content.put(s, sheetContent);
						}
					}
				}
			} catch (Exception e) {
				log.error("解析错误");
			}
		}
		return content;
	}

	/**
	 * 关闭文件流
	 *
	 * @return 关闭机构
	 */
	@SuppressWarnings("unused")
	public boolean close() {
		boolean flag = true;
		if (inputStream != null) {
			try {
				inputStream.close();
			} catch (IOException e) {
				flag = false;
				log.error("Excel文件解析，关闭文件流失败!", e);
			}
		}
		return flag;
	}


	/**
	 * 获取单元格数据内容为字符串类型的数据
	 *
	 * @param cell Excel单元格
	 * @return String 单元格数据内容
	 */
	private String getStringCellValue(Cell cell) {
		String strCell = "";
		if (cell != null) {
			switch (cell.getCellType()) {
				case STRING:
					strCell = cell.getStringCellValue();
					break;
				case FORMULA:
					String formulaValue = cell.getCellFormula();
					if (formulaValue != null && !"".equals(formulaValue)) {
						try {
							strCell = String.valueOf(cell.getNumericCellValue());
						} catch (Exception e) {
							strCell = cell.getStringCellValue();
						}
					}
					break;
				case NUMERIC:
					if (DateUtil.isCellDateFormatted(cell) || cell.getCellStyle().getDataFormat() == 58) {
						strCell = getDateCellValue(cell);
					} else {
						cell.setCellType(CellType.STRING);
						String temp = cell.getStringCellValue();
						if (temp.contains(PoiConstants.SPOT)) {
							strCell = String.valueOf(new Double(temp)).trim();
						} else {
							strCell = temp.trim();
						}
					}
					break;
				case BOOLEAN:
					strCell = String.valueOf(cell.getBooleanCellValue());
					break;
				default:
					strCell = "";
					break;
			}
		}
		return strCell;
	}

	/**
	 * 获取单元格数据内容为日期类型的数据
	 *
	 * @param cell Excel单元格
	 * @return String 单元格数据内容
	 */
	private String getDateCellValue(Cell cell) {
		String result = "";
		try {
			CellType cellType = cell.getCellType();
			if (cellType == NUMERIC) {
				Date date = cell.getDateCellValue();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				result = sdf.format(date);
			} else if (cellType == STRING) {
				String date = getStringCellValue(cell);
				result = date.replaceAll("[年月]", "-").replace("日", "").trim();
			} else if (cellType == BLANK) {
				result = "";
			}
		} catch (Exception e) {
			log.error("Excel文件解析失败，日期格式不正确!", e);
		}
		return result;
	}

}